package com.example.spring.security.demo.config;

import com.example.spring.security.demo.config.mobile.SmsCodeAuthenticationSecurityConfig;
import com.example.spring.security.demo.config.validate.image.ImageValidateCodeFilter;
import com.example.spring.security.demo.config.validate.sms.ValidateCodeFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private SimpleUrlAuthenticationFailureHandler customAuthenticationFailureHandler;
    @Autowired
    private SavedRequestAwareAuthenticationSuccessHandler customAuthenticationSuccessHandler;
    @Autowired
    private ImageValidateCodeFilter imageValidateCodeFilter;
    @Autowired
    private ValidateCodeFilter validateCodeFilter;


    @Autowired
    private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig;

    @Override
    protected void configure(HttpSecurity http) throws Exception {



        http
                .addFilterBefore(validateCodeFilter, AbstractPreAuthenticatedProcessingFilter.class)
                .addFilterBefore(imageValidateCodeFilter,UsernamePasswordAuthenticationFilter.class)
            .formLogin()  //2
                .loginPage("/authentication/require")
                .loginProcessingUrl("/authentication/from") //表单提交默认"/login"，如果要自定义请求路径则在此配置
                .successHandler(customAuthenticationSuccessHandler)
                .failureHandler(customAuthenticationFailureHandler)
                .and()
                .authorizeRequests() //3
                .antMatchers("/index","/authentication/*",
                        "/login.html","/sigin","/code/*","/fail").permitAll() //4

                //.and()
                //.rememberMe()
                // 设置 tokenRepository ，这里默认使用 jdbcTokenRepositoryImpl，意味着我们将从数据库中读取token所代表的用户信息
                //.tokenRepository(persistentTokenRepository())
                // 设置  userDetailsService , 和 认证过程的一样，RememberMe 有专门的 RememberMeAuthenticationProvider ,也就意味着需要 使用UserDetailsService 加载 UserDetails 信息

                .anyRequest().authenticated()
                .and()
                .csrf()
                .disable()
            .apply(smsCodeAuthenticationSecurityConfig)
        ;
        ; //6
    }

}
